#include "mpStringUtils.h"

#include <sstream>
#include <boost/algorithm/string.hpp>

namespace MP{
namespace StringUtils{

////private member
//namespace{
//} //private member

std::string trim_copy(const std::string& s){
    return boost::algorithm::trim_copy(s);
}

std::string trim_copy(const std::string& s, const std::string& trim_value){
    std::string str = s;

    while(stringStartsWith(str, trim_value)) {
        str = str.substr(trim_value.size());
    }

    while (stringEndsWith(str, trim_value)) {
        str = str.substr(0, str.size() - trim_value.size());
    }

    return str;
}


std::string stringToUpper_copy(const std::string& s){
    std::string temp = s;
    stringToUpper(&temp);
    return temp;
}

std::string stringToLower_copy(const std::string& s){
    std::string temp = s;
    stringToLower(&temp);
    return temp;
}


void stringToUpper(std::string* s){
    std::string::iterator end = s->end();
    for (std::string::iterator i = s->begin(); i != end; ++i)
        *i = toupper(static_cast<unsigned char>(*i));
}

void stringToLower(std::string* s){
    std::string::iterator end = s->end();
    for (std::string::iterator i = s->begin(); i != end; ++i)
        *i = tolower(static_cast<unsigned char>(*i));
}

bool stringStartsWith(const std::string& str,
                      const std::string& prefix){
    return boost::starts_with(str,prefix);
}

bool stringEndsWith(const std::string& str,
                    const std::string& suffix){
    return boost::ends_with(str,suffix);
}

bool stringStartsWithIgnoreCase(const std::string& str,
                                const std::string& prefix){
    return boost::istarts_with (str,prefix);
}

bool stringEndsWithIgnoreCase(const std::string& str,
                              const std::string& suffix){
    return boost::iends_with(str,suffix);
}

std::string stringRemovePrefix_copy(const std::string& str,
                                    const std::string& prefix){
    if (stringStartsWith(str, prefix)) {
        return str.substr(prefix.size());
    }
    return str;
}

std::string stringRemoveSuffix_copy(const std::string& str,
                                    const std::string& suffix){
    if (stringEndsWith(str, suffix)) {
        return str.substr(0, str.size() - suffix.size());
    }
    return str;
}

std::string joinStrings(const std::vector<std::string>& str_vec,
                        const std::string& delimiter){
    return boost::algorithm::join(str_vec,delimiter);
    //    std::string ret;
    //    for (std::vector<std::string>::const_iterator c_itr = str_vec.begin();
    //         c_itr != str_vec.end(); ++c_itr) {
    //      if (c_itr + 1 == str_vec.end()) {
    //        ret = ret + *c_itr;
    //      } else {
    //        ret = ret + *c_itr + delimiter;
    //      }
    //    }
    //    return ret;
}


void splitString(const std::string& str,
                 char delim,
                 std::vector<std::string> & vec){
    std::stringstream ss(str);
    std::string item;
    while (std::getline(ss, item, delim)) {
//      if (!item.empty()) {
//        vec.push_back(item);
//      }
        //空的也要
        vec.push_back(item);
    }
}

void splitString(const std::string& str,
                 const std::string& sep,
                 std::vector<std::string> & vec){

    size_t start = 0, index = 0;

    while ((index = str.find(sep, start)) != std::string::npos) {
        //if (index > start) {
        //空的也要
        if (index >= start) {
            vec.push_back(str.substr(start, index - start));
        }

        start = index + sep.size();
        if (start == std::string::npos) {
            return;
        }
    }

    vec.push_back(str.substr(start));
}

bool checkIsIP(const std::string& host){
    int n[4];
    char c[4];
    const char *p = host.c_str();
    if (sscanf(p, "%d%c%d%c%d%c%d%c", &n[0], &c[0], &n[1], &c[1], &n[2], &c[2], &n[3], &c[3]) == 7)
    {
        int i;
        for (i = 0; i < 3; ++i)
            if (c[i] != '.')
                return false;
        for (i = 0; i < 4; ++i)
            if (n[i] > 255 || n[i] < 0)
                return false;
        return true;
    }
    return false;

//    static const std::regex ipPattern("((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])");
//    return std::regex_match(host, ipPattern);
}

}   //END StringUtils
}   //END MP
